// An highlighted block
import 'dart:io';
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_jpf_core/page/base_state_page.dart';
import 'package:flutter_jpf_debug/flutter_jpf_debug.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'dart:ui' as ui;
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
//import 'package:flutter_spterp/api.dart';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import 'package:flutter_jpf_core/util/date_util.dart';

class WhiteboardPage extends CommBasePage {

  @override
  CommBaseState<CommBasePage> getPageState() {
    // TODO: implement getPageState
    return SignAppState();
  }

}

class SignAppState extends CommBaseState<WhiteboardPage> {
  GlobalKey<SignatureState> signatureKey = GlobalKey();// 使跨组件访问状态

  @override
  void initState() {
    super.initState();
  }

  @override
  void initBaseParams() {
    // TODO: implement initBaseParams
  }

  @override
  void initPageData() {
    // TODO: implement initPageData
  }

  @override
  Widget getViewsWidget() {
    return Scaffold(
      body: Signature(key: signatureKey),
      persistentFooterButtons: <Widget>[
        FlatButton(
          child: Text('返回上一级'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        FlatButton(
          child: Text('清除画布'),
          onPressed: () {
            signatureKey.currentState.clearPoints();
          },
        ),
        FlatButton(
          child: Text('保存'),
          onPressed: () {
            saveRenderedImage();
          },
        )
      ],
    );
  }

  saveRenderedImage() async {
    ui.Image compressImage = await signatureKey.currentState.compressImage(prsent: 1000);  // 转成图片

    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;
    var pngBytes = await compressImage.toByteData(format: ui.ImageByteFormat.png);
    String filePath  = path.join(appDocPath, 'dart.png');
    final imageFile = File(filePath);
    await imageFile.writeAsBytesSync(pngBytes.buffer.asInt8List());

    _saveFileToPhotoLibrary(filePath);
    Log.D("width:${compressImage.width},height:${compressImage.height}");

    //var compressImageBytes = await compressImage.toByteData(format: ui.ImageByteFormat.png);
    //submitImage(compressImageBytes,"filePath");
  }

  submitImage(pngBytes,path) async {

    showProgressDialog(msg:"正在保存");
    String timeStr = DateUtil.format(DateTime.now(),format:"yyyyMMddHHmmss");
    String name = "$timeStr.png";
    String url = "http://172.16.56.177/uploadfile/save_image.php";
    FormData map = FormData.fromMap({
      'file': await MultipartFile.fromBytes(pngBytes.buffer.asInt8List(),filename: name,contentType: MediaType('image', 'png')),
      //'file': await MultipartFile.fromFile(path,filename: name,contentType: MediaType('image', 'png'))
    });
    Response response = await Dio().request(
      url,
      data: map,
      options: new Options(method: "POST"),
    );
    hideProgressDialog();
    print(response.data);
    if (response.statusCode == HttpStatus.ok) {
      showToastTip("保存成功");
    }else{
      showToastTip("网络异常");
    }
  }

  _save() async {
    var response = await Dio().get(
        "http://172.16.56.177/uploadfile/upload/20201216_20201216113136YLYBleLockHistoryVC.png",
        options: Options(responseType: ResponseType.bytes));
    final result = await ImageGallerySaver.saveImage(
        Uint8List.fromList(response.data),
        quality: 60,
        name: "hello");
  }

  _saveFileToPhotoLibrary(file) async {
    final result = await ImageGallerySaver.saveFile(file);
    print(result);
  }

}

class Signature extends StatefulWidget {
  Signature({Key key}): super(key: key);

  @override
  State<StatefulWidget> createState() {
    return SignatureState();
  }
}

class SignatureState extends State<Signature> {
  List<Offset> _points = <Offset>[];
  Future<ui.Image> get rendered {
    print("prsent");
    return compressImage(prsent:10);
  }

  Future<ui.Image> compressImage({int prsent=30}) {
    ui.PictureRecorder recorder = ui.PictureRecorder();
    Canvas canvas = Canvas(recorder);

    double rate = 0.01*prsent;
    List<Offset> points = <Offset>[];
    for(int i=0;i<_points.length;i++){
      Offset pi = _points[i];
      if(pi==null){
        points.add(null);
      }else{
        points.add(Offset(pi.dx*rate,pi.dy*rate));
      }
    }
    SignaturePainter painter = SignaturePainter(points: points,prsent: prsent);
    var size = Size(context.size.width*rate, context.size.height*rate);
    painter.paint(canvas, size);
    return recorder.endRecording()
        .toImage(size.width.floor(), size.height.floor());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: GestureDetector(
          onPanUpdate: (DragUpdateDetails details) {
            setState(() {
              RenderBox _object = context.findRenderObject();
              Offset _locationPoints = _object.localToGlobal(details.globalPosition);
              _points = new List.from(_points)..add(_locationPoints);
              //_points.add(_locationPoints);
            });
          },
          onPanEnd: (DragEndDetails details) {
            setState(() {
              _points.add(null);
            });
          },
          child: CustomPaint(
            painter: SignaturePainter(points: _points),
            size: Size.infinite,
          ),
        ),
      ),
    );
  }

  // clearPoints method used to reset the canvas
  // method can be called using
  //   key.currentState.clearPoints();
  void clearPoints() {
    setState(() {
      _points.clear();
    });
  }
}


class SignaturePainter extends CustomPainter {
  // [SignaturePainter] receives points through constructor
  // @points holds the drawn path in the form (x,y) offset;
  // This class responsible for drawing only
  // It won't receive any drag/touch events by draw/user.
  List<Offset> points = <Offset>[];
  int prsent;

  SignaturePainter({this.points,this.prsent:100});

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.black87
      ..strokeCap = StrokeCap.square
      ..strokeWidth = 5.0*this.prsent*0.01;

    for(int i=0; i < points.length - 1; i++) {
      if(points[i] != null && points[i+1] != null) {
        canvas.drawLine(points[i], points[i+1], paint);
      }else{
        /*paint = Paint()
          ..color = Colors.black87
          ..strokeCap = StrokeCap.square
          ..strokeWidth = 1.0;*/
      }
    }
  }

  @override
  bool shouldRepaint(SignaturePainter oldDelegate) {
    return oldDelegate.points != points;
  }

}